讓新同事花了 30 分鐘竟然真的找出有問題的地方,可惡!這個地方我明明就測試了好幾次,甚至還有自動化測試涵蓋到,但新同事覺得有問題的地方,是不是真的是產品 Bug 呢?
畢竟由我這個資深的前輩來判斷的話,可能有失公正。於是請另一位同事交叉比對,看看照步驟從頭操作一次,是否同樣的現象會出現。
bug-verify 執行前會需要前一天留下的完整證據,而這份證據包含保留待測試網址、前置條件、操作步驟、看到的現象、原始證據,以及哪些東西不在這次測試的範圍內,並且把為什麼是 Bug 的理由、信心分數和結論都會拿掉。
由 bug-verify 執行完的結果會有三種:
昨天的完整證據整理一份給負責重現問題的同事的資料:保留受測網址、前置條件、操作步驟、看到的現象、原始證據,以及不在這次測試的範圍內。
輸出的證據預設會放在 output 資料夾下:
output/evidence/20260730-toolshop-oncall-bughunting/packages/C-05-qty-leaks-across-products.md
output/evidence/20260730-toolshop-oncall-bughunting/{candidates.yaml, results.yaml, manifest.md}
output/runs/2026-07-30.yaml — 當天執行的日誌接著我們需要開啟一位不繼承先前對話的 subagent,也就是獨立的子代理人,請它照步驟自己操作。跑完後,要留下自己這輪的截圖、console、network 和 trace,再重新撰寫一份測試結果(verdict)。不能拿昨天執行所留下的截圖,因為我們就是想要確認另一位同事是否真的能夠照著步驟重現問題。
使用下列這句 Prompt 就會開啟新的 session 並且使用 bug-verifier 驗昨天的 C-05 問題:
開啟全新的 session 使用 bug-verifier 驗 C-05
驗證跑完後,我們要看兩件事:另一位同事有沒有看到同樣的現象,以及它有沒有留下這次操作的證據。 這兩件事情都要寫進前面提到的判定結果檔案裡。
C-05 要驗的是「切換商品後,數量欄位會不會沿用上一個商品的值」。負責重現問題的同事實際做了以下操作:
它也看到了前一天回報的現象,因此記為 confirmed。當時的判定檔放在 output/verdicts/V-C-05.yaml,以下是其中的內容:
candidate: "product-detail|quantity-field-not-reset-across-products|route-product-to-product"
verifier: independent-subagent
steps_followed:
- Cleared sessionStorage cart and reloaded
- Navigated to #/product/1 (Combination Pliers)
- Read initial quantity: "1"
- Manually entered "3" into quantity field
- Clicked Related Product link to navigate to #/product/2 without page reload
- Read quantity on product 2 and product name
observed: |
Product 2 (Pliers) - navigated via Related Products link:
- Quantity field value: 3 (LEAKED from product 1!)
verdict: confirmed
independent_evidence:
- verifier-run/C-05-qty-leak.png
讀這份檔案時,可以這樣對照:
| 欄位 | 在交代什麼 |
|---|---|
candidate |
這次驗的是哪一筆問題;這串文字是用來辨認問題的指紋 |
verifier |
由誰執行驗證;這裡是獨立的子代理人 |
steps_followed |
它這次實際做了哪些操作 |
observed |
操作後親眼看到什麼 |
verdict |
這次是否重現成功;confirmed 表示看到同樣的現象 |
independent_evidence |
它這次自己留下的證據存在哪裡 |
這裡的 confirmed 只表示「另一位同事也重現了數量沿用的現象」。為什麼會發生、影響多大,以及能不能開 Bug 單,還需要其他資料才能判斷。
上面是補做後的結果。第一次交回來時,這位負責重現問題的同事,雖然寫了 confirmed,卻沒有附上自己這輪的證據,independent_evidence 是空的。
這就像你的同事說「我也測到了」,但沒有留下任何可以回頭查的材料。依照這次的驗證規則,證據不足時只能記為 inconclusive,不能直接採計為重現成功。
所以這份結果被退回,請他重新操作並保存自己的截圖。重跑後,他仍然看到同樣的現象,也補上了 verifier-run/C-05-qty-leak.png,才接受這次的 confirmed。
independent_evidence 要指向這次驗證所產生的檔案。
前一天共有 8 筆候選問題,當時送驗了其中 6 筆,結果都重現成功,而且各自附上驗證者這輪的證據。另外 2 筆因為分數低,當時為了省預算沒有送驗。它們的狀態是「還沒驗」,不能算通過,也不能當成「驗了但沒重現」。明天會再檢查這兩筆該怎麼處理。
這 6 筆的驗證方式也有一個限制:當時由同一位驗證代理人依序處理,沒有每筆都另開一位。 原因是代理人共用同一個 Playwright MCP 瀏覽器;如果同時操作,就可能互相切走分頁,或改掉對方正在使用的購物車狀態。
這位同事雖然沒有看過之前的判斷理由,但驗到第五筆時,已經知道前四筆都成功了,可能因此更傾向相信下一筆也會成功。因此,執行日誌除了記下六筆結果,也記下這個限制,讓後來讀紀錄的人知道當時是怎麼驗的。
跑完後,每筆候選都要有一份判定檔,記下這次做了哪些操作、看到什麼、最後怎麼判,以及證據存在哪裡。為了方便查找,現在會把同一輪的檔案集中放在一起,路徑格式如下:
output/sessions/<date>_<slug>/verdicts/V-<finding_id>.yaml
<date>_<slug> 代表這輪執行的日期與名稱;<finding_id> 是問題編號,所以 C-05 的判定檔就叫 V-C-05.yaml。前面範例中的 output/verdicts/ 是舊實驗的存放位置,自己練習時使用上面的格式即可。
判定檔裡提到的證據,也要一併保存。今天驗的是 UI,除了截圖等佐證,還需要這輪的 trace,讓接手的人能回看操作過程。前面的 YAML 範例只節錄了部分內容,實際交付時仍要補齊這些資料。若沒有錄到 trace,就先記下原因,並在開單前補齊要求的 UI 證據。純 API 驗證則保存請求與回應,註明這次不涉及瀏覽器操作,因此沒有瀏覽器 trace。
結果和證據存好後,還要把這次的判定補回 Day 20 的 output/calibration.yaml。那份表記著找到問題的同事當初給的信心分數,現在加上驗證結果,就能回頭看:「當初很有把握的問題,後來真的能被別人重現嗎?」
回填時,找到對應的問題,將結果寫進 verifier_verdict 欄位。例如 C-05 重現成功,就填入 confirmed。這一步由負責串接流程的代理人處理,也可以在下一章的開單前檢查時完成;負責重現問題的同事本身不必讀取找到問題的同事的分數。
到這裡,每筆問題就有了驗證結果、這輪的證據,以及更新後的追蹤紀錄。下一章會接著檢查這些資料,確認是否符合開 Bug 單的條件。
首先不能知道知道找到問題的同事的資訊,也不把它的邏輯和分數交給負責重現問題的同事,也免重現的時候失真。 負責重現問題的同事可以讀操作所需的設定與規則,但如果資料裡混進找到問題的同事的結論,就先停下來,整理好輸入後另開一輪。
| verdict | 意思 | 判準 |
|---|---|---|
confirmed |
照步驟跑,自己觀察到同一現象 | 不是「我看了覺得有道理」 |
not-reproduced |
照步驟跑完,現象未出現 | 退回找到問題的同事補證據或降級,不開單、不修 |
inconclusive |
步驟跑不完(被擋、環境壞、資料缺) | 附卡在哪一步 |
每份重跑都需要附上這次的證據,如果沒有就標示為 inconclusive。UI 與 API 留下的檔案可以不同,但一定要有確切的證據顯示我們真的重現了問題。
今天讓另一位沒參與探索的同事,照留下的步驟重新操作。它交回的 confirmed,代表自己也看到了同樣的現象;如果這輪沒看到,就記 not-reproduced,這時候我們還不急著開票出來。
這次六筆送驗的候選都重現成功,但中間過程也出過問題:負責重現問題的同事一度沒附自己的證據,六筆又共用同一位驗證代理人,可能會導致結果失真的限制也需要被記錄下來。
明天會把候選、證據、分數和盲驗結果,做一次開單前的總檢查。前面各每個步驟雖然檢查過一些項目,最後仍要確認它們都符合,才交給開單流程。